home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- __all__ = [
- 'AmbiguityError',
- 'CheckboxControl',
- 'Control',
- 'ControlNotFoundError',
- 'FileControl',
- 'FormParser',
- 'HTMLForm',
- 'HiddenControl',
- 'IgnoreControl',
- 'ImageControl',
- 'IsindexControl',
- 'Item',
- 'ItemCountError',
- 'ItemNotFoundError',
- 'Label',
- 'ListControl',
- 'LocateError',
- 'Missing',
- 'ParseError',
- 'ParseFile',
- 'ParseFileEx',
- 'ParseResponse',
- 'ParseResponseEx',
- 'PasswordControl',
- 'RadioControl',
- 'ScalarControl',
- 'SelectControl',
- 'SubmitButtonControl',
- 'SubmitControl',
- 'TextControl',
- 'TextareaControl',
- 'XHTMLCompatibleFormParser']
-
- try:
- True
- except NameError:
- True = 1
- False = 0
-
-
- try:
- bool
- except NameError:
-
- def bool(expr):
- if expr:
- return True
- else:
- return False
-
-
-
- try:
- import logging
- import inspect
- except ImportError:
-
- def debug(msg, *args, **kwds):
- pass
-
-
- _logger = logging.getLogger('ClientForm')
- OPTIMIZATION_HACK = True
-
- def debug(msg, *args, **kwds):
- if OPTIMIZATION_HACK:
- return None
-
- caller_name = inspect.stack()[1][3]
- extended_msg = '%%s %s' % msg
- extended_args = (caller_name,) + args
- debug = _logger.debug(extended_msg, *extended_args, **kwds)
-
-
- def _show_debug_messages():
- global OPTIMIZATION_HACK
- OPTIMIZATION_HACK = False
- _logger.setLevel(logging.DEBUG)
- handler = logging.StreamHandler(sys.stdout)
- handler.setLevel(logging.DEBUG)
- _logger.addHandler(handler)
-
- import sys
- import urllib
- import urllib2
- import types
- import mimetools
- import copy
- import urlparse
- import htmlentitydefs
- import re
- import random
- from cStringIO import StringIO
- import sgmllib
- sgmllib.charref = re.compile('(x?[0-9a-fA-F]+)[^0-9a-fA-F]')
-
- try:
- import HTMLParser
- except ImportError:
- HAVE_MODULE_HTMLPARSER = False
-
- HAVE_MODULE_HTMLPARSER = True
-
- try:
- import warnings
- except ImportError:
-
- def deprecation(message, stack_offset = 0):
- pass
-
-
-
- def deprecation(message, stack_offset = 0):
- warnings.warn(message, DeprecationWarning, stacklevel = 3 + stack_offset)
-
- VERSION = '0.2.9'
- CHUNK = 1024
- DEFAULT_ENCODING = 'latin-1'
-
- class Missing:
- pass
-
- _compress_re = re.compile('\\s+')
-
- def compress_text(text):
- return _compress_re.sub(' ', text.strip())
-
-
- def normalize_line_endings(text):
- return re.sub('(?:(?<!\\r)\\n)|(?:\\r(?!\\n))', '\r\n', text)
-
-
- def urlencode(query, doseq = False):
- if hasattr(query, 'items'):
- query = query.items()
- else:
-
- try:
- x = len(query)
- if len(query) and type(query[0]) != types.TupleType:
- raise TypeError()
- except TypeError:
- (ty, va, tb) = sys.exc_info()
- raise TypeError('not a valid non-string sequence or mapping object', tb)
-
- l = []
- if not doseq:
- for k, v in query:
- k = urllib.quote_plus(str(k))
- v = urllib.quote_plus(str(v))
- l.append(k + '=' + v)
-
- else:
- for k, v in query:
- k = urllib.quote_plus(str(k))
- if type(v) == types.StringType:
- v = urllib.quote_plus(v)
- l.append(k + '=' + v)
- continue
- if type(v) == types.UnicodeType:
- v = urllib.quote_plus(v.encode('ASCII', 'replace'))
- l.append(k + '=' + v)
- continue
-
- try:
- x = len(v)
- except TypeError:
- v = urllib.quote_plus(str(v))
- l.append(k + '=' + v)
- continue
-
- for elt in v:
- l.append(k + '=' + urllib.quote_plus(str(elt)))
-
-
- return '&'.join(l)
-
-
- def unescape(data, entities, encoding = DEFAULT_ENCODING):
- if data is None or '&' not in data:
- return data
-
-
- def replace_entities(match, entities = entities, encoding = encoding):
- ent = match.group()
- if ent[1] == '#':
- return unescape_charref(ent[2:-1], encoding)
-
- repl = entities.get(ent)
- if repl is not None:
- if type(repl) != type(''):
-
- try:
- repl = repl.encode(encoding)
- except UnicodeError:
- repl = ent
- except:
- None<EXCEPTION MATCH>UnicodeError
-
-
- None<EXCEPTION MATCH>UnicodeError
- else:
- repl = ent
- return repl
-
- return re.sub('?[A-Za-z0-9]+?;', replace_entities, data)
-
-
- def unescape_charref(data, encoding):
- name = data
- base = 10
- if name.startswith('x'):
- name = name[1:]
- base = 16
-
- uc = unichr(int(name, base))
- if encoding is None:
- return uc
- else:
-
- try:
- repl = uc.encode(encoding)
- except UnicodeError:
- repl = '%s;' % data
-
- return repl
-
-
- def get_entitydefs():
- import htmlentitydefs
- latin_1_decode = latin_1_decode
- import codecs
- entitydefs = { }
-
- try:
- htmlentitydefs.name2codepoint
- except AttributeError:
- entitydefs = { }
- for name, char in htmlentitydefs.entitydefs.items():
- uc = latin_1_decode(char)[0]
- if uc.startswith('') and uc.endswith(';'):
- uc = unescape_charref(uc[2:-1], None)
-
- entitydefs['&%s;' % name] = uc
-
-
- for name, codepoint in htmlentitydefs.name2codepoint.items():
- entitydefs['&%s;' % name] = unichr(codepoint)
-
- return entitydefs
-
-
- def issequence(x):
-
- try:
- x[0]
- except (TypeError, KeyError):
- return False
- except IndexError:
- pass
-
- return True
-
-
- def isstringlike(x):
-
- try:
- x + ''
- except:
- return False
-
- return True
-
-
- def choose_boundary():
- nonce = []([ str(random.randint(0, sys.maxint - 1)) for i in (0, 1, 2) ])
- return '-' * 27 + nonce
-
-
- class MimeWriter:
-
- def __init__(self, fp, http_hdrs = None):
- self._http_hdrs = http_hdrs
- self._fp = fp
- self._headers = []
- self._boundary = []
- self._first_part = True
-
-
- def addheader(self, key, value, prefix = 0, add_to_http_hdrs = 0):
- lines = value.split('\r\n')
- while lines and not lines[-1]:
- del lines[-1]
- while lines and not lines[0]:
- del lines[0]
- if add_to_http_hdrs:
- value = ''.join(lines)
- self._http_hdrs.append((key, value))
- else:
- for i in range(1, len(lines)):
- lines[i] = ' ' + lines[i].strip()
-
- value = '\r\n'.join(lines) + '\r\n'
- line = key + ': ' + value
- if prefix:
- self._headers.insert(0, line)
- else:
- self._headers.append(line)
-
-
- def flushheaders(self):
- self._fp.writelines(self._headers)
- self._headers = []
-
-
- def startbody(self, ctype = None, plist = [], prefix = 1, add_to_http_hdrs = 0, content_type = 1):
- if content_type and ctype:
- for name, value in plist:
- ctype = ctype + ';\r\n %s=%s' % (name, value)
-
- self.addheader('Content-type', ctype, prefix = prefix, add_to_http_hdrs = add_to_http_hdrs)
-
- self.flushheaders()
- if not add_to_http_hdrs:
- self._fp.write('\r\n')
-
- self._first_part = True
- return self._fp
-
-
- def startmultipartbody(self, subtype, boundary = None, plist = [], prefix = 1, add_to_http_hdrs = 0, content_type = 1):
- if not boundary:
- pass
- boundary = choose_boundary()
- self._boundary.append(boundary)
- return self.startbody('multipart/' + subtype, [
- ('boundary', boundary)] + plist, prefix = prefix, add_to_http_hdrs = add_to_http_hdrs, content_type = content_type)
-
-
- def nextpart(self):
- boundary = self._boundary[-1]
- if self._first_part:
- self._first_part = False
- else:
- self._fp.write('\r\n')
- self._fp.write('--' + boundary + '\r\n')
- return self.__class__(self._fp)
-
-
- def lastpart(self):
- if self._first_part:
- self.nextpart()
-
- boundary = self._boundary.pop()
- self._fp.write('\r\n--' + boundary + '--\r\n')
-
-
-
- class LocateError(ValueError):
- pass
-
-
- class AmbiguityError(LocateError):
- pass
-
-
- class ControlNotFoundError(LocateError):
- pass
-
-
- class ItemNotFoundError(LocateError):
- pass
-
-
- class ItemCountError(ValueError):
- pass
-
- if HAVE_MODULE_HTMLPARSER:
- SGMLLIB_PARSEERROR = sgmllib.SGMLParseError
-
- class ParseError(sgmllib.SGMLParseError, HTMLParser.HTMLParseError):
- pass
-
- elif hasattr(sgmllib, 'SGMLParseError'):
- SGMLLIB_PARSEERROR = sgmllib.SGMLParseError
-
- class ParseError(sgmllib.SGMLParseError):
- pass
-
- else:
- SGMLLIB_PARSEERROR = RuntimeError
-
- class ParseError(RuntimeError):
- pass
-
-
- class _AbstractFormParser:
-
- def __init__(self, entitydefs = None, encoding = DEFAULT_ENCODING):
- if entitydefs is None:
- entitydefs = get_entitydefs()
-
- self._entitydefs = entitydefs
- self._encoding = encoding
- self.base = None
- self.forms = []
- self.labels = []
- self._current_label = None
- self._current_form = None
- self._select = None
- self._optgroup = None
- self._option = None
- self._textarea = None
- self._global_form = None
- self.start_form([])
- self.end_form()
- self._current_form = self._global_form = self.forms[0]
-
-
- def do_base(self, attrs):
- debug('%s', attrs)
- for key, value in attrs:
- if key == 'href':
- self.base = self.unescape_attr_if_required(value)
- continue
-
-
-
- def end_body(self):
- debug('')
- if self._current_label is not None:
- self.end_label()
-
- if self._current_form is not self._global_form:
- self.end_form()
-
-
-
- def start_form(self, attrs):
- debug('%s', attrs)
- if self._current_form is not self._global_form:
- raise ParseError('nested FORMs')
-
- name = None
- action = None
- enctype = 'application/x-www-form-urlencoded'
- method = 'GET'
- d = { }
- for key, value in attrs:
- if key == 'name':
- name = self.unescape_attr_if_required(value)
- elif key == 'action':
- action = self.unescape_attr_if_required(value)
- elif key == 'method':
- method = self.unescape_attr_if_required(value.upper())
- elif key == 'enctype':
- enctype = self.unescape_attr_if_required(value.lower())
-
- d[key] = self.unescape_attr_if_required(value)
-
- controls = []
- self._current_form = ((name, action, method, enctype), d, controls)
-
-
- def end_form(self):
- debug('')
- if self._current_label is not None:
- self.end_label()
-
- if self._current_form is self._global_form:
- raise ParseError('end of FORM before start')
-
- self.forms.append(self._current_form)
- self._current_form = self._global_form
-
-
- def start_select(self, attrs):
- debug('%s', attrs)
- if self._select is not None:
- raise ParseError('nested SELECTs')
-
- if self._textarea is not None:
- raise ParseError('SELECT inside TEXTAREA')
-
- d = { }
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._select = d
- self._add_label(d)
- self._append_select_control({
- '__select': d })
-
-
- def end_select(self):
- debug('')
- if self._select is None:
- raise ParseError('end of SELECT before start')
-
- if self._option is not None:
- self._end_option()
-
- self._select = None
-
-
- def start_optgroup(self, attrs):
- debug('%s', attrs)
- if self._select is None:
- raise ParseError('OPTGROUP outside of SELECT')
-
- d = { }
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._optgroup = d
-
-
- def end_optgroup(self):
- debug('')
- if self._optgroup is None:
- raise ParseError('end of OPTGROUP before start')
-
- self._optgroup = None
-
-
- def _start_option(self, attrs):
- debug('%s', attrs)
- if self._select is None:
- raise ParseError('OPTION outside of SELECT')
-
- if self._option is not None:
- self._end_option()
-
- d = { }
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._option = { }
- self._option.update(d)
- if self._optgroup and self._optgroup.has_key('disabled') and not self._option.has_key('disabled'):
- self._option['disabled'] = None
-
-
-
- def _end_option(self):
- debug('')
- if self._option is None:
- raise ParseError('end of OPTION before start')
-
- contents = self._option.get('contents', '').strip()
- self._option['contents'] = contents
- if not self._option.has_key('value'):
- self._option['value'] = contents
-
- if not self._option.has_key('label'):
- self._option['label'] = contents
-
- self._option['__select'] = self._select
- self._append_select_control(self._option)
- self._option = None
-
-
- def _append_select_control(self, attrs):
- debug('%s', attrs)
- controls = self._current_form[2]
- name = self._select.get('name')
- controls.append(('select', name, attrs))
-
-
- def start_textarea(self, attrs):
- debug('%s', attrs)
- if self._textarea is not None:
- raise ParseError('nested TEXTAREAs')
-
- if self._select is not None:
- raise ParseError('TEXTAREA inside SELECT')
-
- d = { }
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- self._add_label(d)
- self._textarea = d
-
-
- def end_textarea(self):
- debug('')
- if self._textarea is None:
- raise ParseError('end of TEXTAREA before start')
-
- controls = self._current_form[2]
- name = self._textarea.get('name')
- controls.append(('textarea', name, self._textarea))
- self._textarea = None
-
-
- def start_label(self, attrs):
- debug('%s', attrs)
- if self._current_label:
- self.end_label()
-
- d = { }
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- taken = bool(d.get('for'))
- d['__text'] = ''
- d['__taken'] = taken
- if taken:
- self.labels.append(d)
-
- self._current_label = d
-
-
- def end_label(self):
- debug('')
- label = self._current_label
- if label is None:
- return None
-
- self._current_label = None
- del label['__taken']
-
-
- def _add_label(self, d):
- if self._current_label is not None:
- if not self._current_label['__taken']:
- self._current_label['__taken'] = True
- d['__label'] = self._current_label
-
-
-
-
- def handle_data(self, data):
- debug('%s', data)
- if data[0:2] == '\r\n':
- data = data[2:]
-
- if data[0:1] in ('\n', '\r'):
- data = data[1:]
-
- if self._option is not None:
- map = self._option
- key = 'contents'
- elif self._textarea is not None:
- map = self._textarea
- key = 'value'
- data = normalize_line_endings(data)
- elif self._current_label is not None:
- map = self._current_label
- key = '__text'
- else:
- return None
- if not map.has_key(key):
- map[key] = data
- else:
- map[key] = map[key] + data
-
-
- def do_button(self, attrs):
- debug('%s', attrs)
- d = { }
- d['type'] = 'submit'
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- controls = self._current_form[2]
- type = d['type']
- name = d.get('name')
- type = type + 'button'
- self._add_label(d)
- controls.append((type, name, d))
-
-
- def do_input(self, attrs):
- debug('%s', attrs)
- d = { }
- d['type'] = 'text'
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- controls = self._current_form[2]
- type = d['type']
- name = d.get('name')
- self._add_label(d)
- controls.append((type, name, d))
-
-
- def do_isindex(self, attrs):
- debug('%s', attrs)
- d = { }
- for key, val in attrs:
- d[key] = self.unescape_attr_if_required(val)
-
- controls = self._current_form[2]
- self._add_label(d)
- controls.append(('isindex', None, d))
-
-
- def handle_entityref(self, name):
- self.handle_data(unescape('&%s;' % name, self._entitydefs, self._encoding))
-
-
- def handle_charref(self, name):
- self.handle_data(unescape_charref(name, self._encoding))
-
-
- def unescape_attr(self, name):
- return unescape(name, self._entitydefs, self._encoding)
-
-
- def unescape_attrs(self, attrs):
- escaped_attrs = { }
- for key, val in attrs.items():
-
- try:
- val.items
- except AttributeError:
- escaped_attrs[key] = self.unescape_attr(val)
- continue
-
- escaped_attrs[key] = self.unescape_attrs(val)
-
- return escaped_attrs
-
-
- def unknown_entityref(self, ref):
- self.handle_data('&%s;' % ref)
-
-
- def unknown_charref(self, ref):
- self.handle_data('%s;' % ref)
-
-
- if not HAVE_MODULE_HTMLPARSER:
-
- class XHTMLCompatibleFormParser:
-
- def __init__(self, entitydefs = None, encoding = DEFAULT_ENCODING):
- raise ValueError('HTMLParser could not be imported')
-
-
- else:
-
- class XHTMLCompatibleFormParser(_AbstractFormParser, HTMLParser.HTMLParser):
-
- def __init__(self, entitydefs = None, encoding = DEFAULT_ENCODING):
- HTMLParser.HTMLParser.__init__(self)
- _AbstractFormParser.__init__(self, entitydefs, encoding)
-
-
- def feed(self, data):
-
- try:
- HTMLParser.HTMLParser.feed(self, data)
- except HTMLParser.HTMLParseError:
- exc = None
- raise ParseError(exc)
-
-
-
- def start_option(self, attrs):
- _AbstractFormParser._start_option(self, attrs)
-
-
- def end_option(self):
- _AbstractFormParser._end_option(self)
-
-
- def handle_starttag(self, tag, attrs):
-
- try:
- method = getattr(self, 'start_' + tag)
- except AttributeError:
-
- try:
- method = getattr(self, 'do_' + tag)
- except AttributeError:
- pass
-
- method(attrs)
-
- method(attrs)
-
-
- def handle_endtag(self, tag):
-
- try:
- method = getattr(self, 'end_' + tag)
- except AttributeError:
- pass
-
- method()
-
-
- def unescape(self, name):
- return self.unescape_attr(name)
-
-
- def unescape_attr_if_required(self, name):
- return name
-
-
- def unescape_attrs_if_required(self, attrs):
- return attrs
-
-
-
- class _AbstractSgmllibParser(_AbstractFormParser):
-
- def do_option(self, attrs):
- _AbstractFormParser._start_option(self, attrs)
-
- if sys.version_info[:2] >= (2, 5):
- entity_or_charref = re.compile('&(?:([a-zA-Z][-.a-zA-Z0-9]*)|#(x?[0-9a-fA-F]+))(;?)')
-
- def convert_entityref(self, name):
- return unescape('&%s;' % name, self._entitydefs, self._encoding)
-
-
- def convert_charref(self, name):
- return unescape_charref('%s' % name, self._encoding)
-
-
- def unescape_attr_if_required(self, name):
- return name
-
-
- def unescape_attrs_if_required(self, attrs):
- return attrs
-
- else:
-
- def unescape_attr_if_required(self, name):
- return self.unescape_attr(name)
-
-
- def unescape_attrs_if_required(self, attrs):
- return self.unescape_attrs(attrs)
-
-
-
- class FormParser(_AbstractSgmllibParser, sgmllib.SGMLParser):
-
- def __init__(self, entitydefs = None, encoding = DEFAULT_ENCODING):
- sgmllib.SGMLParser.__init__(self)
- _AbstractFormParser.__init__(self, entitydefs, encoding)
-
-
- def feed(self, data):
-
- try:
- sgmllib.SGMLParser.feed(self, data)
- except SGMLLIB_PARSEERROR:
- exc = None
- raise ParseError(exc)
-
-
-
-
- def _create_bs_classes(bs, icbinbs):
-
- class _AbstractBSFormParser(_AbstractSgmllibParser):
- bs_base_class = None
-
- def __init__(self, entitydefs = None, encoding = DEFAULT_ENCODING):
- _AbstractFormParser.__init__(self, entitydefs, encoding)
- self.bs_base_class.__init__(self)
-
-
- def handle_data(self, data):
- _AbstractFormParser.handle_data(self, data)
- self.bs_base_class.handle_data(self, data)
-
-
- def feed(self, data):
-
- try:
- self.bs_base_class.feed(self, data)
- except SGMLLIB_PARSEERROR:
- exc = None
- raise ParseError(exc)
-
-
-
-
- class RobustFormParser(_AbstractBSFormParser, bs):
- pass
-
- RobustFormParser.bs_base_class = bs
-
- class NestingRobustFormParser(_AbstractBSFormParser, icbinbs):
- pass
-
- NestingRobustFormParser.bs_base_class = icbinbs
- return (RobustFormParser, NestingRobustFormParser)
-
-
- try:
- if sys.version_info[:2] < (2, 2):
- raise ImportError
-
- import BeautifulSoup
- except ImportError:
- pass
-
- (RobustFormParser, NestingRobustFormParser) = _create_bs_classes(BeautifulSoup.BeautifulSoup, BeautifulSoup.ICantBelieveItsBeautifulSoup)
- __all__ += [
- 'RobustFormParser',
- 'NestingRobustFormParser']
-
- def ParseResponseEx(response, select_default = False, form_parser_class = FormParser, request_class = urllib2.Request, entitydefs = None, encoding = DEFAULT_ENCODING, _urljoin = urlparse.urljoin, _urlparse = urlparse.urlparse, _urlunparse = urlparse.urlunparse):
- return _ParseFileEx(response, response.geturl(), select_default, False, form_parser_class, request_class, entitydefs, False, encoding, _urljoin = _urljoin, _urlparse = _urlparse, _urlunparse = _urlunparse)
-
-
- def ParseFileEx(file, base_uri, select_default = False, form_parser_class = FormParser, request_class = urllib2.Request, entitydefs = None, encoding = DEFAULT_ENCODING, _urljoin = urlparse.urljoin, _urlparse = urlparse.urlparse, _urlunparse = urlparse.urlunparse):
- return _ParseFileEx(file, base_uri, select_default, False, form_parser_class, request_class, entitydefs, False, encoding, _urljoin = _urljoin, _urlparse = _urlparse, _urlunparse = _urlunparse)
-
-
- def ParseResponse(response, *args, **kwds):
- return _ParseFileEx(response, response.geturl(), *args, **kwds)[1:]
-
-
- def ParseFile(file, base_uri, *args, **kwds):
- return _ParseFileEx(file, base_uri, *args, **kwds)[1:]
-
-
- def _ParseFileEx(file, base_uri, select_default = False, ignore_errors = False, form_parser_class = FormParser, request_class = urllib2.Request, entitydefs = None, backwards_compat = False, encoding = DEFAULT_ENCODING, _urljoin = urlparse.urljoin, _urlparse = urlparse.urlparse, _urlunparse = urlparse.urlunparse):
- if backwards_compat:
- deprecation('operating in backwards-compatibility mode', 1)
-
- fp = form_parser_class(entitydefs, encoding)
- while None:
- data = file.read(CHUNK)
-
- try:
- fp.feed(data)
- except ParseError:
- e = None
- e.base_uri = base_uri
- raise
-
- if len(data) != CHUNK:
- break
- continue
- continue
- if fp.base is not None:
- base_uri = fp.base
-
- labels = []
- id_to_labels = { }
- for l in fp.labels:
- label = Label(l)
- labels.append(label)
- for_id = l['for']
- coll = id_to_labels.get(for_id)
- if coll is None:
- id_to_labels[for_id] = [
- label]
- continue
- coll.append(label)
-
- forms = []
- for name, action, method, enctype in fp.forms:
- attrs = None
- controls = None
- if action is None:
- action = base_uri
- else:
- action = _urljoin(base_uri, action)
- form = HTMLForm(action, method, enctype, name, attrs, request_class, forms, labels, id_to_labels, backwards_compat)
- form._urlparse = _urlparse
- form._urlunparse = _urlunparse
- for ii in range(len(controls)):
- (type, name, attrs) = controls[ii]
- form.new_control(type, name, attrs, select_default = select_default, index = ii * 10)
-
- forms.append(form)
-
- for form in forms:
- form.fixup()
-
- return forms
-
-
- class Label:
-
- def __init__(self, attrs):
- self.id = attrs.get('for')
- self._text = attrs.get('__text').strip()
- self._ctext = compress_text(self._text)
- self.attrs = attrs
- self._backwards_compat = False
-
-
- def __getattr__(self, name):
- if name == 'text':
- if self._backwards_compat:
- return self._text
- else:
- return self._ctext
-
- return getattr(Label, name)
-
-
- def __setattr__(self, name, value):
- if name == 'text':
- raise AttributeError('text attribute is read-only')
-
- self.__dict__[name] = value
-
-
- def __str__(self):
- return '<Label(id=%r, text=%r)>' % (self.id, self.text)
-
-
-
- def _get_label(attrs):
- text = attrs.get('__label')
- if text is not None:
- return Label(text)
- else:
- return None
-
-
- class Control:
-
- def __init__(self, type, name, attrs, index = None):
- raise NotImplementedError()
-
-
- def add_to_form(self, form):
- self._form = form
- form.controls.append(self)
-
-
- def fixup(self):
- pass
-
-
- def is_of_kind(self, kind):
- raise NotImplementedError()
-
-
- def clear(self):
- raise NotImplementedError()
-
-
- def __getattr__(self, name):
- raise NotImplementedError()
-
-
- def __setattr__(self, name, value):
- raise NotImplementedError()
-
-
- def pairs(self):
- return [ (k, v) for i, k, v in self._totally_ordered_pairs() ]
-
-
- def _totally_ordered_pairs(self):
- raise NotImplementedError()
-
-
- def _write_mime_data(self, mw, name, value):
- mw2 = mw.nextpart()
- mw2.addheader('Content-disposition', 'form-data; name="%s"' % name, 1)
- f = mw2.startbody(prefix = 0)
- f.write(value)
-
-
- def __str__(self):
- raise NotImplementedError()
-
-
- def get_labels(self):
- res = []
- if self._label:
- res.append(self._label)
-
- if self.id:
- res.extend(self._form._id_to_labels.get(self.id, ()))
-
- return res
-
-
-
- class ScalarControl(Control):
-
- def __init__(self, type, name, attrs, index = None):
- self._index = index
- self._label = _get_label(attrs)
- self.__dict__['type'] = type.lower()
- self.__dict__['name'] = name
- self._value = attrs.get('value')
- self.disabled = attrs.has_key('disabled')
- self.readonly = attrs.has_key('readonly')
- self.id = attrs.get('id')
- self.attrs = attrs.copy()
- self._clicked = False
- self._urlparse = urlparse.urlparse
- self._urlunparse = urlparse.urlunparse
-
-
- def __getattr__(self, name):
- if name == 'value':
- return self.__dict__['_value']
- else:
- raise AttributeError("%s instance has no attribute '%s'" % (self.__class__.__name__, name))
-
-
- def __setattr__(self, name, value):
- if name == 'value':
- if not isstringlike(value):
- raise TypeError('must assign a string')
- elif self.readonly:
- raise AttributeError("control '%s' is readonly" % self.name)
- elif self.disabled:
- raise AttributeError("control '%s' is disabled" % self.name)
-
- self.__dict__['_value'] = value
- elif name in ('name', 'type'):
- raise AttributeError('%s attribute is readonly' % name)
- else:
- self.__dict__[name] = value
-
-
- def _totally_ordered_pairs(self):
- name = self.name
- value = self.value
- if name is None and value is None or self.disabled:
- return []
-
- return [
- (self._index, name, value)]
-
-
- def clear(self):
- if self.readonly:
- raise AttributeError("control '%s' is readonly" % self.name)
-
- self.__dict__['_value'] = None
-
-
- def __str__(self):
- name = self.name
- value = self.value
- if name is None:
- name = '<None>'
-
- if value is None:
- value = '<None>'
-
- infos = []
- if self.disabled:
- infos.append('disabled')
-
- if self.readonly:
- infos.append('readonly')
-
- info = ', '.join(infos)
- if info:
- info = ' (%s)' % info
-
- return '<%s(%s=%s)%s>' % (self.__class__.__name__, name, value, info)
-
-
-
- class TextControl(ScalarControl):
-
- def __init__(self, type, name, attrs, index = None):
- ScalarControl.__init__(self, type, name, attrs, index)
- if self.type == 'hidden':
- self.readonly = True
-
- if self._value is None:
- self._value = ''
-
-
-
- def is_of_kind(self, kind):
- return kind == 'text'
-
-
-
- class FileControl(ScalarControl):
-
- def __init__(self, type, name, attrs, index = None):
- ScalarControl.__init__(self, type, name, attrs, index)
- self._value = None
- self._upload_data = []
-
-
- def is_of_kind(self, kind):
- return kind == 'file'
-
-
- def clear(self):
- if self.readonly:
- raise AttributeError("control '%s' is readonly" % self.name)
-
- self._upload_data = []
-
-
- def __setattr__(self, name, value):
- if name in ('value', 'name', 'type'):
- raise AttributeError('%s attribute is readonly' % name)
- else:
- self.__dict__[name] = value
-
-
- def add_file(self, file_object, content_type = None, filename = None):
- if not hasattr(file_object, 'read'):
- raise TypeError('file-like object must have read method')
-
- if content_type is not None and not isstringlike(content_type):
- raise TypeError('content type must be None or string-like')
-
- if filename is not None and not isstringlike(filename):
- raise TypeError('filename must be None or string-like')
-
- if content_type is None:
- content_type = 'application/octet-stream'
-
- self._upload_data.append((file_object, content_type, filename))
-
-
- def _totally_ordered_pairs(self):
- if self.name is None or self.disabled:
- return []
-
- return [
- (self._index, self.name, '')]
-
-
- def _write_mime_data(self, mw, _name, _value):
- if len(self._upload_data) == 1:
- (file_object, content_type, filename) = self._upload_data[0]
- mw2 = mw.nextpart()
- if not filename or '; filename="%s"' % filename:
- pass
- fn_part = ''
- disp = 'form-data; name="%s"%s' % (self.name, fn_part)
- mw2.addheader('Content-disposition', disp, prefix = 1)
- fh = mw2.startbody(content_type, prefix = 0)
- fh.write(file_object.read())
- elif len(self._upload_data) != 0:
- mw2 = mw.nextpart()
- disp = 'form-data; name="%s"' % self.name
- mw2.addheader('Content-disposition', disp, prefix = 1)
- fh = mw2.startmultipartbody('mixed', prefix = 0)
- for file_object, content_type, filename in self._upload_data:
- mw3 = mw2.nextpart()
- if not filename or '; filename="%s"' % filename:
- pass
- fn_part = ''
- disp = 'file%s' % fn_part
- mw3.addheader('Content-disposition', disp, prefix = 1)
- fh2 = mw3.startbody(content_type, prefix = 0)
- fh2.write(file_object.read())
-
- mw2.lastpart()
-
-
-
- def __str__(self):
- name = self.name
- if name is None:
- name = '<None>'
-
- if not self._upload_data:
- value = '<No files added>'
- else:
- value = []
- for file, ctype, filename in self._upload_data:
- if filename is None:
- value.append('<Unnamed file>')
- continue
- value.append(filename)
-
- value = ', '.join(value)
- info = []
- if self.disabled:
- info.append('disabled')
-
- if self.readonly:
- info.append('readonly')
-
- info = ', '.join(info)
- if info:
- info = ' (%s)' % info
-
- return '<%s(%s=%s)%s>' % (self.__class__.__name__, name, value, info)
-
-
-
- class IsindexControl(ScalarControl):
-
- def __init__(self, type, name, attrs, index = None):
- ScalarControl.__init__(self, type, name, attrs, index)
- if self._value is None:
- self._value = ''
-
-
-
- def is_of_kind(self, kind):
- return kind in ('text', 'clickable')
-
-
- def _totally_ordered_pairs(self):
- return []
-
-
- def _click(self, form, coord, return_type, request_class = urllib2.Request):
- parts = self._urlparse(form.action)
- rest = parts[:-2]
- (query, frag) = parts[-2:]
- parts = rest + (urllib.quote_plus(self.value), None)
- url = self._urlunparse(parts)
- req_data = (url, None, [])
- if return_type == 'pairs':
- return []
- elif return_type == 'request_data':
- return req_data
- else:
- return request_class(url)
-
-
- def __str__(self):
- value = self.value
- if value is None:
- value = '<None>'
-
- infos = []
- if self.disabled:
- infos.append('disabled')
-
- if self.readonly:
- infos.append('readonly')
-
- info = ', '.join(infos)
- if info:
- info = ' (%s)' % info
-
- return '<%s(%s)%s>' % (self.__class__.__name__, value, info)
-
-
-
- class IgnoreControl(ScalarControl):
-
- def __init__(self, type, name, attrs, index = None):
- ScalarControl.__init__(self, type, name, attrs, index)
- self._value = None
-
-
- def is_of_kind(self, kind):
- return False
-
-
- def __setattr__(self, name, value):
- if name == 'value':
- raise AttributeError("control '%s' is ignored, hence read-only" % self.name)
- elif name in ('name', 'type'):
- raise AttributeError('%s attribute is readonly' % name)
- else:
- self.__dict__[name] = value
-
-
-
- class Item:
-
- def __init__(self, control, attrs, index = None):
- label = _get_label(attrs)
- if not label or [
- label]:
- pass
- self.__dict__.update({
- 'name': attrs['value'],
- '_labels': [],
- 'attrs': attrs,
- '_control': control,
- 'disabled': attrs.has_key('disabled'),
- '_selected': False,
- 'id': attrs.get('id'),
- '_index': index })
- control.items.append(self)
-
-
- def get_labels(self):
- res = []
- res.extend(self._labels)
- if self.id:
- res.extend(self._control._form._id_to_labels.get(self.id, ()))
-
- return res
-
-
- def __getattr__(self, name):
- if name == 'selected':
- return self._selected
-
- raise AttributeError(name)
-
-
- def __setattr__(self, name, value):
- if name == 'selected':
- self._control._set_selected_state(self, value)
- elif name == 'disabled':
- self.__dict__['disabled'] = bool(value)
- else:
- raise AttributeError(name)
-
-
- def __str__(self):
- res = self.name
- if self.selected:
- res = '*' + res
-
- if self.disabled:
- res = '(%s)' % res
-
- return res
-
-
- def __repr__(self):
- attrs = [
- ('name', self.name),
- ('id', self.id)] + self.attrs.items()
- return ' '.join % ([], []([ '%s=%r' % (k, v) for k, v in attrs ]))
-
-
-
- def disambiguate(items, nr, **kwds):
- msgs = []
- for key, value in kwds.items():
- msgs.append('%s=%r' % (key, value))
-
- msg = ' '.join(msgs)
- if not items:
- raise ItemNotFoundError(msg)
-
- if nr is None:
- if len(items) > 1:
- raise AmbiguityError(msg)
-
- nr = 0
-
- if len(items) <= nr:
- raise ItemNotFoundError(msg)
-
- return items[nr]
-
-
- class ListControl(Control):
- _label = None
-
- def __init__(self, type, name, attrs = { }, select_default = False, called_as_base_class = False, index = None):
- if not called_as_base_class:
- raise NotImplementedError()
-
- self.__dict__['type'] = type.lower()
- self.__dict__['name'] = name
- self._value = attrs.get('value')
- self.disabled = False
- self.readonly = False
- self.id = attrs.get('id')
- self._closed = False
- self.items = []
- self._form = None
- self._select_default = select_default
- self._clicked = False
-
-
- def clear(self):
- self.value = []
-
-
- def is_of_kind(self, kind):
- if kind == 'list':
- return True
- elif kind == 'multilist':
- return bool(self.multiple)
- elif kind == 'singlelist':
- return not (self.multiple)
- else:
- return False
-
-
- def get_items(self, name = None, label = None, id = None, exclude_disabled = False):
- if name is not None and not isstringlike(name):
- raise TypeError('item name must be string-like')
-
- if label is not None and not isstringlike(label):
- raise TypeError('item label must be string-like')
-
- if id is not None and not isstringlike(id):
- raise TypeError('item id must be string-like')
-
- items = []
- compat = self._form.backwards_compat
- for o in self.items:
- if exclude_disabled and o.disabled:
- continue
-
- if name is not None and o.name != name:
- continue
-
- if label is not None:
- for l in o.get_labels():
- if (compat or l.text == label or not compat) and l.text.find(label) > -1:
- break
- continue
-
-
- if id is not None and o.id != id:
- continue
-
- items.append(o)
-
- return items
-
-
- def get(self, name = None, label = None, id = None, nr = None, exclude_disabled = False):
- if nr is None and self._form.backwards_compat:
- nr = 0
-
- items = self.get_items(name, label, id, exclude_disabled)
- return disambiguate(items, nr, name = name, label = label, id = id)
-
-
- def _get(self, name, by_label = False, nr = None, exclude_disabled = False):
- if by_label:
- name = None
- label = name
- else:
- name = name
- label = None
- return self.get(name, label, nr, exclude_disabled)
-
-
- def toggle(self, name, by_label = False, nr = None):
- deprecation('item = control.get(...); item.selected = not item.selected')
- o = self._get(name, by_label, nr)
- self._set_selected_state(o, not (o.selected))
-
-
- def set(self, selected, name, by_label = False, nr = None):
- deprecation('control.get(...).selected = <boolean>')
- self._set_selected_state(self._get(name, by_label, nr), selected)
-
-
- def _set_selected_state(self, item, action):
- if self.disabled:
- raise AttributeError("control '%s' is disabled" % self.name)
-
- if self.readonly:
- raise AttributeError("control '%s' is readonly" % self.name)
-
- action == bool(action)
- compat = self._form.backwards_compat
- if not compat and item.disabled:
- raise AttributeError('item is disabled')
- elif compat and item.disabled and action:
- raise AttributeError('item is disabled')
-
- if self.multiple:
- item.__dict__['_selected'] = action
- elif not action:
- item.__dict__['_selected'] = False
- else:
- for o in self.items:
- o.__dict__['_selected'] = False
-
- item.__dict__['_selected'] = True
-
-
- def toggle_single(self, by_label = None):
- deprecation('control.items[0].selected = not control.items[0].selected')
- if len(self.items) != 1:
- raise ItemCountError("'%s' is not a single-item control" % self.name)
-
- item = self.items[0]
- self._set_selected_state(item, not (item.selected))
-
-
- def set_single(self, selected, by_label = None):
- deprecation('control.items[0].selected = <boolean>')
- if len(self.items) != 1:
- raise ItemCountError("'%s' is not a single-item control" % self.name)
-
- self._set_selected_state(self.items[0], selected)
-
-
- def get_item_disabled(self, name, by_label = False, nr = None):
- deprecation('control.get(...).disabled')
- return self._get(name, by_label, nr).disabled
-
-
- def set_item_disabled(self, disabled, name, by_label = False, nr = None):
- deprecation('control.get(...).disabled = <boolean>')
- self._get(name, by_label, nr).disabled = disabled
-
-
- def set_all_items_disabled(self, disabled):
- for o in self.items:
- o.disabled = disabled
-
-
-
- def get_item_attrs(self, name, by_label = False, nr = None):
- deprecation('control.get(...).attrs')
- return self._get(name, by_label, nr).attrs
-
-
- def close_control(self):
- self._closed = True
-
-
- def add_to_form(self, form):
- self._form = form
- if self.name is None:
- Control.add_to_form(self, form)
- else:
- for ii in range(len(form.controls) - 1, -1, -1):
- control = form.controls[ii]
- if control.name == self.name and control.type == self.type:
- if control._closed:
- Control.add_to_form(self, form)
- else:
- control.merge_control(self)
- break
- continue
-
-
-
- def merge_control(self, control):
- self.items.extend(control.items)
-
-
- def fixup(self):
- for o in self.items:
- o.__dict__['_control'] = self
-
-
-
- def __getattr__(self, name):
- pass
-
-
- def __setattr__(self, name, value):
- if name == 'value':
- if self.disabled:
- raise AttributeError("control '%s' is disabled" % self.name)
-
- if self.readonly:
- raise AttributeError("control '%s' is readonly" % self.name)
-
- self._set_value(value)
- elif name in ('name', 'type', 'multiple'):
- raise AttributeError('%s attribute is readonly' % name)
- else:
- self.__dict__[name] = value
-
-
- def _set_value(self, value):
- if value is None or isstringlike(value):
- raise TypeError('ListControl, must set a sequence')
-
- if not value:
- compat = self._form.backwards_compat
- for o in self.items:
- if not (o.disabled) or compat:
- o.selected = False
- continue
-
- elif self.multiple:
- self._multiple_set_value(value)
- elif len(value) > 1:
- raise ItemCountError('single selection list, must set sequence of length 0 or 1')
- else:
- self._single_set_value(value)
-
-
- def _get_items(self, name, target = 1):
- all_items = self.get_items(name)
- items = _[1]
- on = []
- off = []
- for o in items:
- if o.selected:
- on.append(o)
- continue
- None if len(items) < target else []
- off.append(o)
-
- return (on, off)
-
-
- def _single_set_value(self, value):
- (on, off) = self._get_items(value[0])
- if not on:
- off[0].selected = True
-
-
-
- def _multiple_set_value(self, value):
- compat = self._form.backwards_compat
- turn_on = []
- turn_off = _[1]
- names = { }
- for nn in value:
- if nn in names.keys():
- names[nn] += 1
- continue
- []
- names[nn] = 1
-
- for name, count in names.items():
- (on, off) = self._get_items(name, count)
- for i in range(count):
- if on:
- item = on[0]
- del on[0]
- del turn_off[turn_off.index(item)]
- continue
- []
- item = off[0]
- del off[0]
- turn_on.append(item)
-
-
- for item in turn_off:
- item.selected = False
-
- for item in turn_on:
- item.selected = True
-
-
-
- def set_value_by_label(self, value):
- if isstringlike(value):
- raise TypeError(value)
-
- if not (self.multiple) and len(value) > 1:
- raise ItemCountError('single selection list, must set sequence of length 0 or 1')
-
- items = []
- for nn in value:
- found = self.get_items(label = nn)
- for o in found:
- if self._form.backwards_compat or o not in items:
- items.append(o)
- break
- continue
- None if len(found) > 1 else []
- else:
- raise ItemNotFoundError(nn)
-
- self.value = []
- for o in items:
- o.selected = True
-
-
-
- def get_value_by_label(self):
- res = []
- compat = self._form.backwards_compat
- for o in self.items:
- if (not (o.disabled) or compat) and o.selected:
- for l in o.get_labels():
- if l.text:
- res.append(l.text)
- break
- continue
-
-
- return res
-
-
- def possible_items(self, by_label = False):
- deprecation('[item.name for item in self.items]')
- if by_label:
- res = []
- for o in self.items:
- for l in o.get_labels():
- if l.text:
- res.append(l.text)
- break
- continue
-
-
- return res
-
- return [ o.name for o in self.items ]
-
-
- def _totally_ordered_pairs(self):
- pass
-
-
- def __str__(self):
- name = self.name
- if name is None:
- name = '<None>'
-
- display = [ str(o) for o in self.items ]
- infos = []
- if self.readonly:
- infos.append('readonly')
-
- info = ', '.join(infos)
- if info:
- info = ' (%s)' % info
-
- return '<%s(%s=[%s])%s>' % (self.__class__.__name__, name, ', '.join(display), info)
-
-
-
- class RadioControl(ListControl):
-
- def __init__(self, type, name, attrs, select_default = False, index = None):
- attrs.setdefault('value', 'on')
- ListControl.__init__(self, type, name, attrs, select_default, called_as_base_class = True, index = index)
- self.__dict__['multiple'] = False
- o = Item(self, attrs, index)
- o.__dict__['_selected'] = attrs.has_key('checked')
-
-
- def fixup(self):
- ListControl.fixup(self)
- found = _[1]
-
-
- def get_labels(self):
- return []
-
-
-
- class CheckboxControl(ListControl):
-
- def __init__(self, type, name, attrs, select_default = False, index = None):
- attrs.setdefault('value', 'on')
- ListControl.__init__(self, type, name, attrs, select_default, called_as_base_class = True, index = index)
- self.__dict__['multiple'] = True
- o = Item(self, attrs, index)
- o.__dict__['_selected'] = attrs.has_key('checked')
-
-
- def get_labels(self):
- return []
-
-
-
- class SelectControl(ListControl):
-
- def __init__(self, type, name, attrs, select_default = False, index = None):
- self.attrs = attrs['__select'].copy()
- self.__dict__['_label'] = _get_label(self.attrs)
- self.__dict__['id'] = self.attrs.get('id')
- self.__dict__['multiple'] = self.attrs.has_key('multiple')
- contents = attrs.get('contents')
- attrs = attrs.copy()
- del attrs['__select']
- ListControl.__init__(self, type, name, self.attrs, select_default, called_as_base_class = True, index = index)
- self.disabled = self.attrs.has_key('disabled')
- self.readonly = self.attrs.has_key('readonly')
- if attrs.has_key('value'):
- o = Item(self, attrs, index)
- o.__dict__['_selected'] = attrs.has_key('selected')
- label = attrs.get('label')
- if label:
- o._labels.append(Label({
- '__text': label }))
- if contents and contents != label:
- o._labels.append(Label({
- '__text': contents }))
-
- elif contents:
- o._labels.append(Label({
- '__text': contents }))
-
-
-
-
- def fixup(self):
- ListControl.fixup(self)
- found = _[1]
- if not found:
- if not (self.multiple) or self._select_default:
- for o in self.items:
- if not o.disabled:
- was_disabled = self.disabled
- self.disabled = False
-
- try:
- o.selected = True
- finally:
- o.disabled = was_disabled
-
- break
- continue
- []
-
-
- elif not self.multiple:
- for o in found[:-1]:
- o.selected = False
-
-
-
-
-
- class SubmitControl(ScalarControl):
-
- def __init__(self, type, name, attrs, index = None):
- ScalarControl.__init__(self, type, name, attrs, index)
- if self.value is None:
- self.value = ''
-
- self.readonly = True
-
-
- def get_labels(self):
- res = []
- if self.value:
- res.append(Label({
- '__text': self.value }))
-
- res.extend(ScalarControl.get_labels(self))
- return res
-
-
- def is_of_kind(self, kind):
- return kind == 'clickable'
-
-
- def _click(self, form, coord, return_type, request_class = urllib2.Request):
- self._clicked = coord
- r = form._switch_click(return_type, request_class)
- self._clicked = False
- return r
-
-
- def _totally_ordered_pairs(self):
- if not self._clicked:
- return []
-
- return ScalarControl._totally_ordered_pairs(self)
-
-
-
- class ImageControl(SubmitControl):
-
- def __init__(self, type, name, attrs, index = None):
- SubmitControl.__init__(self, type, name, attrs, index)
- self.readonly = False
-
-
- def _totally_ordered_pairs(self):
- clicked = self._clicked
- if self.disabled or not clicked:
- return []
-
- name = self.name
- if name is None:
- return []
-
- pairs = [
- (self._index, '%s.x' % name, str(clicked[0])),
- (self._index + 1, '%s.y' % name, str(clicked[1]))]
- value = self._value
- if value:
- pairs.append((self._index + 2, name, value))
-
- return pairs
-
- get_labels = ScalarControl.get_labels
-
-
- class PasswordControl(TextControl):
- pass
-
-
- class HiddenControl(TextControl):
- pass
-
-
- class TextareaControl(TextControl):
- pass
-
-
- class SubmitButtonControl(SubmitControl):
- pass
-
-
- def is_listcontrol(control):
- return control.is_of_kind('list')
-
-
- class HTMLForm:
- type2class = {
- 'text': TextControl,
- 'password': PasswordControl,
- 'hidden': HiddenControl,
- 'textarea': TextareaControl,
- 'isindex': IsindexControl,
- 'file': FileControl,
- 'button': IgnoreControl,
- 'buttonbutton': IgnoreControl,
- 'reset': IgnoreControl,
- 'resetbutton': IgnoreControl,
- 'submit': SubmitControl,
- 'submitbutton': SubmitButtonControl,
- 'image': ImageControl,
- 'radio': RadioControl,
- 'checkbox': CheckboxControl,
- 'select': SelectControl }
-
- def __init__(self, action, method = 'GET', enctype = 'application/x-www-form-urlencoded', name = None, attrs = None, request_class = urllib2.Request, forms = None, labels = None, id_to_labels = None, backwards_compat = True):
- self.action = action
- self.method = method
- self.enctype = enctype
- self.name = name
- if attrs is not None:
- self.attrs = attrs.copy()
- else:
- self.attrs = { }
- self.controls = []
- self._request_class = request_class
- self._forms = forms
- self._labels = labels
- self._id_to_labels = id_to_labels
- self.backwards_compat = backwards_compat
- self._urlunparse = urlparse.urlunparse
- self._urlparse = urlparse.urlparse
-
-
- def __getattr__(self, name):
- if name == 'backwards_compat':
- return self._backwards_compat
-
- return getattr(HTMLForm, name)
-
-
- def __setattr__(self, name, value):
- if name == 'backwards_compat':
- name = '_backwards_compat'
- value = bool(value)
- for cc in self.controls:
-
- try:
- items = cc.items
- except AttributeError:
- continue
- continue
-
- for ii in items:
- for ll in ii.get_labels():
- ll._backwards_compat = value
-
-
-
-
- self.__dict__[name] = value
-
-
- def new_control(self, type, name, attrs, ignore_unknown = False, select_default = False, index = None):
- type = type.lower()
- klass = self.type2class.get(type)
- if klass is None:
- if ignore_unknown:
- klass = IgnoreControl
- else:
- klass = TextControl
-
- a = attrs.copy()
- if issubclass(klass, ListControl):
- control = klass(type, name, a, select_default, index)
- else:
- control = klass(type, name, a, index)
- if type == 'select' and len(attrs) == 1:
- for ii in range(len(self.controls) - 1, -1, -1):
- ctl = self.controls[ii]
- if ctl.type == 'select':
- ctl.close_control()
- break
- continue
-
-
- control.add_to_form(self)
- control._urlparse = self._urlparse
- control._urlunparse = self._urlunparse
-
-
- def fixup(self):
- for control in self.controls:
- control.fixup()
-
- self.backwards_compat = self._backwards_compat
-
-
- def __str__(self):
- if not self.name or self.name + ' ':
- pass
- header = '%s%s %s %s' % ('', self.method, self.action, self.enctype)
- rep = [
- header]
- for control in self.controls:
- rep.append(' %s' % str(control))
-
- return '<%s>' % '\n'.join(rep)
-
-
- def __getitem__(self, name):
- return self.find_control(name).value
-
-
- def __contains__(self, name):
- return bool(self.find_control(name))
-
-
- def __setitem__(self, name, value):
- control = self.find_control(name)
-
- try:
- control.value = value
- except AttributeError:
- e = None
- raise ValueError(str(e))
-
-
-
- def get_value(self, name = None, type = None, kind = None, id = None, nr = None, by_label = False, label = None):
- if by_label:
- deprecation('form.get_value_by_label(...)')
-
- c = self.find_control(name, type, kind, id, label = label, nr = nr)
- if by_label:
-
- try:
- meth = c.get_value_by_label
- except AttributeError:
- raise NotImplementedError("control '%s' does not yet support by_label" % c.name)
-
- return meth()
- else:
- return c.value
-
-
- def set_value(self, value, name = None, type = None, kind = None, id = None, nr = None, by_label = False, label = None):
- if by_label:
- deprecation('form.get_value_by_label(...)')
-
- c = self.find_control(name, type, kind, id, label = label, nr = nr)
- if by_label:
-
- try:
- meth = c.set_value_by_label
- except AttributeError:
- raise NotImplementedError("control '%s' does not yet support by_label" % c.name)
-
- meth(value)
- else:
- c.value = value
-
-
- def get_value_by_label(self, name = None, type = None, kind = None, id = None, label = None, nr = None):
- c = self.find_control(name, type, kind, id, label = label, nr = nr)
- return c.get_value_by_label()
-
-
- def set_value_by_label(self, value, name = None, type = None, kind = None, id = None, label = None, nr = None):
- c = self.find_control(name, type, kind, id, label = label, nr = nr)
- c.set_value_by_label(value)
-
-
- def set_all_readonly(self, readonly):
- for control in self.controls:
- control.readonly = bool(readonly)
-
-
-
- def clear_all(self):
- for control in self.controls:
- control.clear()
-
-
-
- def clear(self, name = None, type = None, kind = None, id = None, nr = None, label = None):
- c = self.find_control(name, type, kind, id, label = label, nr = nr)
- c.clear()
-
-
- def possible_items(self, name = None, type = None, kind = None, id = None, nr = None, by_label = False, label = None):
- c = self._find_list_control(name, type, kind, id, label, nr)
- return c.possible_items(by_label)
-
-
- def set(self, selected, item_name, name = None, type = None, kind = None, id = None, nr = None, by_label = False, label = None):
- self._find_list_control(name, type, kind, id, label, nr).set(selected, item_name, by_label)
-
-
- def toggle(self, item_name, name = None, type = None, kind = None, id = None, nr = None, by_label = False, label = None):
- self._find_list_control(name, type, kind, id, label, nr).toggle(item_name, by_label)
-
-
- def set_single(self, selected, name = None, type = None, kind = None, id = None, nr = None, by_label = None, label = None):
- self._find_list_control(name, type, kind, id, label, nr).set_single(selected)
-
-
- def toggle_single(self, name = None, type = None, kind = None, id = None, nr = None, by_label = None, label = None):
- self._find_list_control(name, type, kind, id, label, nr).toggle_single()
-
-
- def add_file(self, file_object, content_type = None, filename = None, name = None, id = None, nr = None, label = None):
- self.find_control(name, 'file', id = id, label = label, nr = nr).add_file(file_object, content_type, filename)
-
-
- def click(self, name = None, type = None, id = None, nr = 0, coord = (1, 1), request_class = urllib2.Request, label = None):
- return self._click(name, type, id, label, nr, coord, 'request', self._request_class)
-
-
- def click_request_data(self, name = None, type = None, id = None, nr = 0, coord = (1, 1), request_class = urllib2.Request, label = None):
- return self._click(name, type, id, label, nr, coord, 'request_data', self._request_class)
-
-
- def click_pairs(self, name = None, type = None, id = None, nr = 0, coord = (1, 1), label = None):
- return self._click(name, type, id, label, nr, coord, 'pairs', self._request_class)
-
-
- def find_control(self, name = None, type = None, kind = None, id = None, predicate = None, nr = None, label = None):
- if name is None and type is None and kind is None and id is None and label is None and predicate is None and nr is None:
- raise ValueError('at least one argument must be supplied to specify control')
-
- return self._find_control(name, type, kind, id, label, predicate, nr)
-
-
- def _find_list_control(self, name = None, type = None, kind = None, id = None, label = None, nr = None):
- if name is None and type is None and kind is None and id is None and label is None and nr is None:
- raise ValueError('at least one argument must be supplied to specify control')
-
- return self._find_control(name, type, kind, id, label, is_listcontrol, nr)
-
-
- def _find_control(self, name, type, kind, id, label, predicate, nr):
- if name is not None and name is not Missing and not isstringlike(name):
- raise TypeError('control name must be string-like')
-
- if type is not None and not isstringlike(type):
- raise TypeError('control type must be string-like')
-
- if kind is not None and not isstringlike(kind):
- raise TypeError('control kind must be string-like')
-
- if id is not None and not isstringlike(id):
- raise TypeError('control id must be string-like')
-
- if label is not None and not isstringlike(label):
- raise TypeError('control label must be string-like')
-
- if predicate is not None and not callable(predicate):
- raise TypeError('control predicate must be callable')
-
- if nr is not None and nr < 0:
- raise ValueError('control number must be a positive integer')
-
- orig_nr = nr
- found = None
- ambiguous = False
- if nr is None and self.backwards_compat:
- nr = 0
-
- for control in self.controls:
- if name is not None or name != control.name:
- if name is not Missing or control.name is not None:
- continue
-
- if type is not None and type != control.type:
- continue
-
- if kind is not None and not control.is_of_kind(kind):
- continue
-
- if id is not None and id != control.id:
- continue
-
- if predicate and not predicate(control):
- continue
-
- if label:
- for l in control.get_labels():
- if l.text.find(label) > -1:
- break
- continue
-
-
- if nr is not None:
- if nr == 0:
- return control
-
- nr -= 1
- continue
-
- if found:
- ambiguous = True
- break
-
- found = control
-
- if found and not ambiguous:
- return found
-
- description = []
- if name is not None:
- description.append('name %s' % repr(name))
-
- if type is not None:
- description.append("type '%s'" % type)
-
- if kind is not None:
- description.append("kind '%s'" % kind)
-
- if id is not None:
- description.append("id '%s'" % id)
-
- if label is not None:
- description.append("label '%s'" % label)
-
- if predicate is not None:
- description.append('predicate %s' % predicate)
-
- if orig_nr:
- description.append('nr %d' % orig_nr)
-
- description = ', '.join(description)
- if ambiguous:
- raise AmbiguityError('more than one control matching ' + description)
- elif not found:
- raise ControlNotFoundError('no control matching ' + description)
-
-
-
- def _click(self, name, type, id, label, nr, coord, return_type, request_class = urllib2.Request):
-
- try:
- control = self._find_control(name, type, 'clickable', id, label, None, nr)
- except ControlNotFoundError:
- if name is not None and type is not None and id is not None or nr != 0:
- raise
-
- return self._switch_click(return_type, request_class)
-
- return control._click(self, coord, return_type, request_class)
-
-
- def _pairs(self):
- return [ (k, v) for i, k, v, c_i in self._pairs_and_controls() ]
-
-
- def _pairs_and_controls(self):
- pairs = []
- for control_index in range(len(self.controls)):
- control = self.controls[control_index]
- for ii, key, val in control._totally_ordered_pairs():
- pairs.append((ii, key, val, control_index))
-
-
- pairs.sort()
- return pairs
-
-
- def _request_data(self):
- method = self.method.upper()
- parts = self._urlparse(self.action)
- rest = parts[:-2]
- (query, frag) = parts[-2:]
- if method == 'GET':
- if self.enctype != 'application/x-www-form-urlencoded':
- raise ValueError("unknown GET form encoding type '%s'" % self.enctype)
-
- parts = rest + (urlencode(self._pairs()), None)
- uri = self._urlunparse(parts)
- return (uri, None, [])
- elif method == 'POST':
- parts = rest + (query, None)
- uri = self._urlunparse(parts)
- if self.enctype == 'application/x-www-form-urlencoded':
- return (uri, urlencode(self._pairs()), [
- ('Content-type', self.enctype)])
- elif self.enctype == 'multipart/form-data':
- data = StringIO()
- http_hdrs = []
- mw = MimeWriter(data, http_hdrs)
- f = mw.startmultipartbody('form-data', add_to_http_hdrs = True, prefix = 0)
- for ii, k, v, control_index in self._pairs_and_controls():
- self.controls[control_index]._write_mime_data(mw, k, v)
-
- mw.lastpart()
- return (uri, data.getvalue(), http_hdrs)
- else:
- raise ValueError("unknown POST form encoding type '%s'" % self.enctype)
- else:
- raise ValueError("Unknown method '%s'" % method)
-
-
- def _switch_click(self, return_type, request_class = urllib2.Request):
- if return_type == 'pairs':
- return self._pairs()
- elif return_type == 'request_data':
- return self._request_data()
- else:
- req_data = self._request_data()
- req = request_class(req_data[0], req_data[1])
- for key, val in req_data[2]:
- add_hdr = req.add_header
- if key.lower() == 'content-type':
-
- try:
- add_hdr = req.add_unredirected_header
- except AttributeError:
- pass
- except:
- None<EXCEPTION MATCH>AttributeError
-
-
- None<EXCEPTION MATCH>AttributeError
- add_hdr(key, val)
-
- return req
-
-
-